//Direct 3D Framework C++ File
//Defines the framework for working with DirectX
//Jeffrey Denton	January 12, 2011
#include "GraphicsHandler.h"

//=====CONSTRUCTORS
GraphicsHandler::GraphicsHandler():mD3DDevice(NULL){}
//=====INITIALIZE
bool GraphicsHandler::Initialize(HWND hWnd, HINSTANCE hInstance, bool WndOpen)
{
	if(!InitDevice(hWnd,WndOpen))	
		return false;
	m3DEngine.Initialize(mD3DDevice);
	m2DEngine.Initialize(mD3DDevice);
	WorldLight.Init(mD3DDevice);

	return true;
}
bool GraphicsHandler::InitDevice(HWND hWnd, bool WndOpen)
{
	IDirect3D9* mD3DObject = NULL;
	mD3DObject = Direct3DCreate9(D3D_SDK_VERSION);			

	if(mD3DObject == NULL){return false;}	//Validate Direct 3D Object is not NULL

	D3DCAPS9 DeviceCaps;
	mD3DObject->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &DeviceCaps);

	DWORD DeviceBehavior = 0;	//Determine what type of vertext  processing to use


	if(DeviceCaps.VertexProcessingCaps != 0)					//Set the processing
		DeviceBehavior |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else DeviceBehavior |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;	


	//Set Pure Device Support if Hardware can handle it
	if(DeviceCaps.DevCaps & D3DDEVCAPS_PUREDEVICE && DeviceBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING)
		DeviceBehavior |= D3DCREATE_PUREDEVICE;

	//Set Direct 3D Parameters for Presenting, initialize to NULL first
	D3DPRESENT_PARAMETERS DeviceParameters;
	ZeroMemory(&DeviceParameters, sizeof(DeviceParameters));

	DeviceParameters.Windowed					= WndOpen;									//Is the Application FullScreen  or windowed
	DeviceParameters.hDeviceWindow				= hWnd;										//Application Window Handle
	DeviceParameters.BackBufferCount			= 1;										//Number of Buffer Windows Needed
	DeviceParameters.BackBufferFormat			= D3DFMT_UNKNOWN;							//Back Buffer Format, defaults to 32-bit
	DeviceParameters.BackBufferHeight			= SCREEN_HEIGHT;							//Set Buffer to window size and
	DeviceParameters.BackBufferWidth			= SCREEN_WIDTH;								//check that resolution is supported
	DeviceParameters.EnableAutoDepthStencil		= TRUE;										//Turn on the Z-buffer
	DeviceParameters.AutoDepthStencilFormat		= D3DFMT_D24S8;								//32 bit format: 24 Depth, NowCoord.Y Stencil
	DeviceParameters.MultiSampleType			= D3DMULTISAMPLE_NONE;						//No Multisampling
	DeviceParameters.MultiSampleQuality			= 0;										//MultiSampling is off
	DeviceParameters.FullScreen_RefreshRateInHz = WndOpen ? 0 : D3DPRESENT_RATE_DEFAULT;	//Refresh Rate for Fullscreen
	DeviceParameters.Flags						= D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;		//Meant to Increase Performance
	DeviceParameters.PresentationInterval		= D3DPRESENT_INTERVAL_DEFAULT;				//Waste no time presenting back buffer
	DeviceParameters.SwapEffect					= D3DSWAPEFFECT_DISCARD;					//Discard the Back Buffer

	//Create Object Device
	HRESULT hr = mD3DObject->CreateDevice(D3DADAPTER_DEFAULT,
		D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,
		&DeviceParameters, &mD3DDevice);
	if(FAILED(hr)){return false;}	//validate Object was created


	mD3DObject->Release();
	return true;
}
//=====UPDATE
void GraphicsHandler::Update(DrawList& drawlist)
{
	//m3DEngine.Update(mD3DDevice,drawlist);
	GameCamera.Move();
}
void GraphicsHandler::CheckDevice()
{
	// Watch for our window being covered, minimized or otherwise deactivated
	if (NULL == mD3DDevice){return;}							//If we have lost our D3DDevice pointer, just return
	HRESULT hDevState = mD3DDevice->TestCooperativeLevel();	// Check for lost device 
	switch (hDevState)
	{
	case D3DERR_DEVICELOST:		
		::OutputDebugString("Device lost"); //If the device is lost return		
		::Sleep(100);						//check in the next frame
		return;		

	case D3DERR_DEVICENOTRESET:
		if (FAILED(mD3DDevice->Reset(&D3D_PP)))
		{
			::OutputDebugString("Reset failed");
			return;
		}
		break;
	}// Done checking for deactivation and lost devices; all is well
}
//=====RENDER
bool GraphicsHandler::Draw(DrawList& drawlist,SpriteList& SpriteList, int CurrentState)
{
	mD3DDevice->SetTransform(D3DTS_VIEW, &GameCamera.SetView());		//Camera

	mD3DDevice->Clear(0, NULL, 	D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
		D3DCOLOR_ARGB(150,150,150,150),	1.0f, 0);
	mD3DDevice->BeginScene();

	m2DEngine.Render2D(SpriteList,CurrentState);
	m3DEngine.Render(mD3DDevice,drawlist);

	mD3DDevice->EndScene();						//Stop Drawing the Scene
	mD3DDevice->Present(NULL, NULL, NULL, NULL);//Display the Screen

	return true;
}
//=====
DXTEXTURE GraphicsHandler::GetTexture(int ID) 
{
	return m2DEngine.GetTexture(ID);
}
//=====SHUTDOWN
bool GraphicsHandler::Shutdown()
{

	if(mD3DDevice)
	{
		mD3DDevice->Release();
		mD3DDevice = 0;
	}

	return true;
}
